package com.yoooya.base.admin.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.yoooya.base.admin.shiro.CustomRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class SpringShiroConfig {

	@Autowired
	private CustomRealm realm;

	public SpringShiroConfig() {
		System.out.println("SpringShiroConfig init ......");
	}
	@Bean(name = "lifecycleBeanPostProcessor")
	public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
		return new LifecycleBeanPostProcessor();
	}

	@Bean
	@DependsOn("lifecycleBeanPostProcessor")
	public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
		DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
		creator.setProxyTargetClass(true);
		creator.setUsePrefix(true);
		return creator;
	}


	@Bean
	public MethodInvokingFactoryBean getMethodInvokingFactoryBean(@Qualifier("securityManager")SecurityManager securityManager) {
		MethodInvokingFactoryBean methodInvokingFactoryBean=new MethodInvokingFactoryBean();
		methodInvokingFactoryBean.setStaticMethod("org.apache.shiro.SecurityUtils.setSecurityManager");
		methodInvokingFactoryBean.setArguments(new Object[]{securityManager});
		return methodInvokingFactoryBean;
	}



	//get
	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager")SecurityManager securityManager) {
		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
		return authorizationAttributeSourceAdvisor;
	}


	//get
	@Bean(name = "shiroFilter")
	public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager")SecurityManager securityManager){
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		shiroFilterFactoryBean.setLoginUrl("/index.jsp");
		shiroFilterFactoryBean.setSuccessUrl("/index.jsp");
		shiroFilterFactoryBean.setUnauthorizedUrl("/index.jsp");
		shiroFilterFactoryBean.setSecurityManager(securityManager);

		loadShiroFilterChain(shiroFilterFactoryBean);

		return shiroFilterFactoryBean;

	}

	//get
	@Bean(name = "sessionManager")
	public DefaultWebSessionManager sessionManager(){
		DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
		sessionManager.setGlobalSessionTimeout(86400000);
		sessionManager.setDeleteInvalidSessions(true);
		return sessionManager;
	}

	//get
	@Bean(name = "shiroCacheManager")
	public EhCacheManager shiroCacheManager(){
		EhCacheManager shiroCacheManager = new EhCacheManager();
		shiroCacheManager.setCacheManagerConfigFile("classpath:shiro-ehcache.xml");
		return shiroCacheManager;
	}

	//get
	@Bean(name = "securityManager")
	public DefaultWebSecurityManager securityManager(@Qualifier("shiroCacheManager") EhCacheManager shiroCacheManager,
													 @Qualifier("sessionManager") DefaultWebSessionManager sessionManager) {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		securityManager.setRealm(realm);
		securityManager.setCacheManager(shiroCacheManager);
		securityManager.setSessionManager(sessionManager);
		return securityManager;
	}

	//get
	private void loadShiroFilterChain(ShiroFilterFactoryBean shiroFilterFactoryBean) {
		Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
//        filterChainDefinitionMap.put("/securitry/**", "anon");
//        filterChainDefinitionMap.put("/api/**", "anon");
//        filterChainDefinitionMap.put("/favicon.ico", "anon");
//        filterChainDefinitionMap.put("/api-docs/**", "anon");
//        filterChainDefinitionMap.put("/lib/**", "anon");
		// filterChainDefinitionMap.put("/**", "authc");
//        filterChainDefinitionMap.put("/logout", "logout");
		filterChainDefinitionMap.put("/index.jsp", "anon");
		filterChainDefinitionMap.put("/common/**", "anon");
		filterChainDefinitionMap.put("/layuiAdmin/**", "anon");
		filterChainDefinitionMap.put("/layuiAdmin.std-v1.2.1/**", "anon");
		filterChainDefinitionMap.put("/**/login/**", "anon");
		filterChainDefinitionMap.put("/**", "anon");
		/*
		 * filterChainDefinitionMap.put("/mydemo/login", "anon");
		 * filterChainDefinitionMap.put("/mydemo/getVerifyCodeImage", "anon");
		 * filterChainDefinitionMap.put("/main**", "authc");
		 * filterChainDefinitionMap.put("/user/info**", "authc");
		 * filterChainDefinitionMap.put("/admin/listUser**",
		 * "authc,perms[admin:manage]");
		 */
		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
	}

	/*@Bean(name = "shiroDialect")
	public ShiroDialect shiroDialect() {
		return new ShiroDialect();
	}*/

}
